//
//  OperationQueueManager.swift
//  ScaffoldKit
//
//  Created by SuXinDe on 2018/7/29.
//  Copyright © 2018年 su xinde. All rights reserved.
//

import UIKit

public class OperationQueueManager: NSObject {

    
    public static let shared = OperationQueueManager(name: "Queuer")
    
    /// Queuer OperationQueue.
    public let queue = OperationQueue()

    public var operationCount: Int {
        return queue.operationCount
    }
    
    public var qualityOfService: QualityOfService {
        get {
            return queue.qualityOfService
        }
        set {
            queue.qualityOfService = newValue
        }
    }
    
    public var isExecuting: Bool {
        return !queue.isSuspended
    }
    
    public var maxConcurrentOperationCount: Int {
        get {
            return queue.maxConcurrentOperationCount
        }
        set {
            queue.maxConcurrentOperationCount = newValue
        }
    }
    
    public init(name: String,
                maxConcurrentOperationCount: Int = Int.max,
                qualityOfService: QualityOfService = .default) {
        super.init()
        queue.name = name
        self.maxConcurrentOperationCount = maxConcurrentOperationCount
        self.qualityOfService = qualityOfService
    }
    
    public func addOperation(_ operation: @escaping () -> Void) {
        queue.addOperation(operation)
    }
    
    public func addOperation(_ operation: Operation) {
        queue.addOperation(operation)
    }
    
    public func addChainedOperations(_ operations: [Operation],
                                     completionHandler: (()->Void)? = nil) {
        for (index, operation) in operations.enumerated() {
            if index > 0 {
                operation.addDependency(operations[index-1])
            }
            addOperation(operation)
        }
        guard let completionHandler = completionHandler else {
            return
        }
        let completionOperation = BlockOperation(block: completionHandler)
        if !operations.isEmpty {
            completionOperation.addDependency(operations[operations.count-1])
        }
        addOperation(completionOperation)
    }
    
    public func addChainedOperations(_ operations: Operation...,
                                     completionHandler: (()->Void)? = nil) {
        addChainedOperations(operations,
                             completionHandler: completionHandler)
    }
    
    public func cancelAll() {
        queue.cancelAllOperations()
    }
    
    public func pause() {
        queue.isSuspended = true
        for operation in queue.operations where operation is ConcurrentOperation {
            guard let op = operation as? ConcurrentOperation else {
                continue
            }
            op.pause()
        }
    }
    
    public func resume() {
        queue.isSuspended = false
        for operation in queue.operations where operation is ConcurrentOperation {
            guard let op = operation as? ConcurrentOperation else {
                continue
            }
            op.resume()
        }
    }
    
    public func waitUntilAllOperationsAreFinished() {
        queue.waitUntilAllOperationsAreFinished()
    }
    
}
